﻿//
//  Csv.hpp
//  JewelsJunior
//
//  Created by Lixiaolong on 2021/5/7.
//

#ifndef Csv_hpp
#define Csv_hpp

#include <stdio.h>
#include <vector>
#include <string>
#include <map>

class Csv {
public:
	std::vector<std::string> head = {};
	std::vector<std::vector<std::string>> body = {};
	char separated = ',';
public:
    Csv();
    Csv(const char& separated);
    /**
     * @brief Csv
     * @param csv 第一行是字段行的数据
     * @param separated 分隔符
     */
	Csv(const std::string& csv, const char& separated=',');
    /**
     * @brief Csv
     * @param csv
     * @param head 是否存在字段行
     * @param separated 分隔符
     */
	Csv(const std::string& csv, const bool& head, const char& separated=',');
    /**
     * @brief Csv
     * @param csv 第一行是字段行的数据
     * @param separated 分隔符
     */
	Csv(const std::vector<std::vector<std::string>>& csv, const char& separated=',');
    /**
     * @brief Csv
     * @param csv
     * @param head 第一行是否是字段行
     * @param separated 分隔符
     */
	Csv(const std::vector<std::vector<std::string>>& csv, const bool& head, const char& separated=',');
    /**
     * @brief Csv
     * @param body
     * @param head 字段行
     * @param separated 分隔符
     */
	Csv(const std::vector<std::vector<std::string>>& body, const std::vector<std::string>& head, const char& separated=',');
    /**
     * @brief Csv
     * @param head 字段行
     * @param separated 分隔符
     */
    Csv(const std::vector<std::string>& head, const char& separated=',');
public:
    bool empty() const {return head.empty() && body.empty();}

    size_t row_count() const {return body.size();}
    size_t column_count() const {return body.empty() ? 0 : body[0].size();}
public:
    void newline() {body.push_back({});}

    void push_id() {push_back((uint32_t)body.size());}

    void push_back() {body.back().push_back("");}
    void push_back(const int32_t& number) {body.back().push_back(std::to_string(number));}
    void push_back(const uint32_t& number) {body.back().push_back(std::to_string(number));}
    void push_back(const std::string& text) {body.back().push_back(text);}

    void push_back(const char* text) {body.back().push_back(text);}
public:
	void erase(const std::string& key);
    void erase_row(const size_t& row);
    void erase_column(const size_t& column);

	std::map<std::string, std::string> map(const size_t& r) const;
public:
    operator std::string() const {return to_string();}
public:
    std::string to_string() const {return to_string(separated);}
    std::string to_string(const char& separated) const;
private:
	enum class State {
		kUnquoted,
		kQuoted,//起始引号
		kQuoted2,//有起始引号的中间引号
		kQuoted3,//无起始引号的中间引号
	};
    static std::string join(const std::vector<std::string>& items, const char& separated);
    static void trim(std::string& text);
    static void trim_left(std::string& text);
    static void trim_right(std::string& text);
};

#endif /* Csv_hpp */
